home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright (C) 1994, Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
- * the contents of this file may not be disclosed to third parties, copied or
- * duplicated in any form, in whole or in part, without the prior written
- * permission of Silicon Graphics, Inc.
- *
- * RESTRICTED RIGHTS LEGEND:
- * Use, duplication or disclosure by the Government is subject to restrictions
- * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
- * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
- * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
- * rights reserved under the Copyright Laws of the United States.
- */
- #include <stdio.h>
- #include <stdlib.h>
- #include "Entry.h"
- #include "Utils.h"
-
- #define PRINT_WIDTH 80
- #define PRINT_LEADER 22
- #define PRINT_INDENT 2
- #define PRINT_MARGIN 2
-
- const EntryKindInfo entryKindList[] = {
- { E_single, "Single Instance" },
- { E_repeatDaily, "Each Day" },
- { E_repeatWeekDaily, "Each Weekday" },
- { E_repeatWeekly, "Each Week" },
- { E_repeatBiWeekly, "Every Other Week" },
- { E_repeatMonthlyDate, "Each Month, Same Date" },
- { E_repeatMonthlyDay, "Each Month, Same Weekday" },
- { E_repeatMonthlyDateEnd, "Each Month, Same Days From End" },
- { E_repeatMonthlyDayEnd, "Each Month, Same Weekday From End" },
- { E_repeatYearly, "Each Year" },
- };
-
- const int entryKindCount = sizeof(entryKindList) / sizeof(EntryKindInfo);
-
- Entry::Entry()
- {
- _day = 0;
- _month = 0;
- _year = 0;
- _start = 0;
- _length= 0;
-
- _notifyPopup = 1;
- _notifyBell = 1;
- _notifyMail = 0;
- _notifyCommand = strdup("");
-
- _kind = E_single;
- _annotate = 1;
- setAlarmFired(0, ALL_NOTIFICATIONS);
- _next = NULL;
- _next2 = NULL;
- _advance = strdup("");
- _text = strdup("");
- _data = NULL;
- _snoozeData = NULL;
- _alarmInfo = new EntryAlarmInfo;
-
- _alarmInfo->entry = this;
- _alarmInfo->alarm = NULL;
- _alarmInfo->data = NULL;
- }
-
- Entry::~Entry()
- {
- free(_advance);
- free(_text);
- delete _alarmInfo;
- free(_notifyCommand);
- }
-
- void
- Entry::setNotifyCommand(char *v)
- {
- free(_notifyCommand);
- _notifyCommand = strdup(v);
- }
-
- void
- Entry::setAlarmFired(int v, int alarmIndex)
- {
- int each;
-
- if (alarmIndex != ALL_NOTIFICATIONS) {
- _alarmFired[alarmIndex] = v;
- } else {
- for (each=0; each<MAX_ALARM_NOTIFICATIONS; each++) {
- _alarmFired[each] = v;
- }
- }
- }
-
-
- int
- Entry::setAlarmAdvance(char *str)
- {
- char *newstr;
-
- if (newstr = reformatAdvanceString(str)) {
- free(_advance);
- _advance = newstr;
- return 1;
- } else {
- return 0;
- }
- }
-
- int
- Entry::setText(char *t)
- {
- free(_text);
- _text = strdup(t);
- return 1;
- }
-
- int
- Entry::alarmApplies(int time, int *alarmIndex, int unfiredOnly)
- {
- int mins;
- char *current, *remainder;
-
- current = alarmAdvance();
- *alarmIndex = 0;
- while (current) {
- mins = parseAdvance(current, &remainder);
- if ((!unfiredOnly || !_alarmFired[*alarmIndex]) &&
- // This doesn't work across midnight
- mins != -1 && mins < MINS_IN_DAY && start() <= time+mins) {
- return 1;
- }
- current = remainder;
- (*alarmIndex)++;
- }
- if (unfiredOnly) {
- return alarmApplies(time, alarmIndex, 0);
- } else {
- return 0;
- }
- }
-
- int
- Entry::alarmApplies(int d, int m, int y, int *alarmIndex,
- int *matchDay, int *matchMonth, int *matchYear,
- int unfiredOnly)
- {
- int mins, days;
- char *current, *remainder;
-
- current = alarmAdvance();
- *alarmIndex = 0;
- while (current) {
- mins = parseAdvance(current, &remainder);
- if ((!unfiredOnly || !_alarmFired[*alarmIndex]) &&
- mins != -1 && mins >= MINS_IN_DAY) {
- days = mins/MINS_IN_DAY;
- if (daysInAdvance(days, d, m, y, matchDay, matchMonth, matchYear)) {
- return 1;
- }
- }
- current = remainder;
- (*alarmIndex)++;
- }
- if (unfiredOnly) {
- return alarmApplies(d, m, y, alarmIndex, matchDay, matchMonth, matchYear,
- 0);
- } else {
- return 0;
- }
- }
-
- void
- Entry::setDate(int day, int month, int year)
- {
- _day = day;
- _month = month;
- _year = year;
- }
-
- int
- Entry::readEntry(FILE *fd, int version)
- {
- int k, v;
- char adv[MAXSTR], str[MAXSTR];
-
- if (!readInt(fd, &_start) ||
- !readInt(fd, &_length) ||
- !readInt(fd, &k)) {
- return 0;
- }
- if (version == 4) {
- if (!readInt(fd, &v)) {
- return 0;
- } else {
- _notifyPopup = _notifyBell = v;
- _notifyMail = 0;
- _notifyCommand = strdup("");
- }
- } else {
- if (!readInt(fd, &_notifyPopup) ||
- !readInt(fd, &_notifyBell) ||
- !readInt(fd, &_notifyMail) ||
- !readStr(fd, str)) {
- return 0;
- } else {
- setNotifyCommand(str);
- }
- }
- if (version == 4) {
- if (!readInt(fd, &v)) {
- return 0;
- } else {
- sprintf(adv, "%d min", v);
- }
- } else {
- if (!readStr(fd, adv)) {
- return 0;
- }
- }
- if (!readInt(fd, &_annotate) ||
- !readStr(fd, str)) {
- return 0;
- } else {
- _kind = (EntryKind) k;
- setAlarmAdvance(adv);
- setText(str);
- return 1;
- }
- }
-
- void
- Entry::writeEntry(FILE *fd, int annotate)
- {
- writeInt(fd, _start, annotate ? "Start Time (mins)" : NULL);
- writeInt(fd, _length, annotate ? "Length (mins)" : NULL);
- writeInt(fd, (int) _kind, annotate ? "Repeating Kind" : NULL);
- writeInt(fd, _notifyPopup, annotate ? "Notification Popup?" : NULL);
- writeInt(fd, _notifyBell, annotate ? "Notification Bell?" : NULL);
- writeInt(fd, _notifyMail, annotate ? "Notification Mail?" : NULL);
- writeStr(fd, _notifyCommand);
- writeStr(fd, _advance);
- writeInt(fd, _annotate, annotate ? "Annotate Month View?" : NULL);
- writeStr(fd, _text);
- }
-
- void
- Entry::printEntry(FILE *fd, int clock24)
- {
- int hour, min, chars, space;
- char str[MAXSTR], *p, *q;
-
- for (space=0; space<PRINT_MARGIN; space++) {
- fprintf(fd, " ");
- }
- chars = PRINT_MARGIN;
-
- hour = _start/60;
- min = _start % 60;
- formatTime(hour, min, clock24, str);
- fprintf(fd, "%s", str);
- chars += strlen(str);
-
- hour = (_start+_length)/60;
- min = (_start+_length) % 60;
- formatTime(hour, min, clock24, str);
- fprintf(fd, "-%s", str);
- chars += 1+strlen(str);
-
- for (space=chars; space<PRINT_LEADER-PRINT_INDENT; space++) {
- fprintf(fd, " ");
- }
-
- p = _text;
-
- while (strlen(p) > PRINT_WIDTH-PRINT_LEADER) {
- q = strrchr(p+PRINT_WIDTH-PRINT_LEADER, ' ');
- if (!q) {
- q = p+PRINT_WIDTH-PRINT_LEADER;
- }
- while (p <= q) {
- fprintf(fd, "%c", *p);
- p++;
- }
- fprintf(fd, "\n");
- p = q+1;
- }
-
- fputs(_text, fd);
- fprintf(fd, "\n");
- }
-
- int
- Entry::daysInAdvance(int days, int d, int m, int y,
- int *matchDay, int *matchMonth, int *matchYear)
- {
- if (compareDates(d, m, y, _day, _month, _year) == 1) {
- // Alarm already happened
- return 0;
- } else {
- augmentDate(d, m, y, days, matchDay, matchMonth, matchYear);
- return (computeDayDifference(_day, _month, _year, d, m, y) == days);
- }
- }
-
- char *
- Entry::reformatAdvanceString(char *str)
- {
- char *current, *remain, newstr[MAXSTR];
- int mins;
-
- strcpy(newstr, "");
- current = str;
- while (current &&
- (mins = parseAdvance(current, &remain)) != -1) {
- if (current != str) {
- strcat(newstr, ", ");
- }
- if (mins >= MINS_IN_DAY) {
- sprintf(newstr+strlen(newstr), "%d day", mins/MINS_IN_DAY);
- if (mins/MINS_IN_DAY > 1) {
- strcat(newstr, "s");
- }
- } else if (mins && mins % MINS_IN_HOUR == 0) {
- sprintf(newstr+strlen(newstr), "%d hour", mins/MINS_IN_HOUR);
- if (mins/MINS_IN_HOUR > 1) {
- strcat(newstr, "s");
- }
- } else {
- sprintf(newstr+strlen(newstr), "%d min", mins);
- if (mins > 1) {
- strcat(newstr, "s");
- }
- }
- current = remain;
- }
- if (current) {
- return NULL;
- } else {
- return strdup(newstr);
- }
- }
-
- int
- Entry::parseAdvance(char *str, char **remainder)
- {
- int num;
- char *p, *q, old;
-
- while (*str == ' ' || *str == '\t') {
- str++;
- }
- p = str;
- while (*p >= '0' && *p <= '9') {
- p++;
- }
- if (p == str) {
- // No value
- *remainder = NULL;
- return -1;
- }
- old = *p;
- *p = '\0';
- num = atoi(str);
- *p = old;
- while (*p == ' ' || *p == '\t') {
- p++;
- }
- if (*p == ',') {
- *remainder = p+1;
- return num;
- } else if (*p == '\0') {
- *remainder = NULL;
- return num;
- } else { q = p;
- while (*p != ',' && *p != '\0') {
- p++;
- }
- if (*p == ',') {
- *remainder = p+1;
- } else if (*p == '\0') {
- *remainder = NULL;
- }
- if (!strncasecmp(q, "min", 3)) {
- return num;
- } else if (!strncasecmp(q, "hour", 4)) {
- return num*MINS_IN_HOUR;
- } else if (!strncasecmp(q, "day", 3)) {
- return num*MINS_IN_DAY;
- }
- }
- return -1;
- }
-
- /**********************************************************************/
-
- RepeatingEntry::RepeatingEntry()
- {
- _repeatEndDay = 0;
- _repeatEndMonth = 0;
- _repeatEndYear = 0;
- }
-
- RepeatingEntry::~RepeatingEntry()
- {
- }
-
- int
- RepeatingEntry::repeatApplies(int day, int month, int year)
- {
- int result, weekday, diff;
-
- if (compareDates(day, month, year, _day, _month, _year) < 0) {
- return 0;
- } else if (_repeatEndDay && _repeatEndMonth && _repeatEndYear &&
- compareDates(day, month, year, _repeatEndDay, _repeatEndMonth,
- _repeatEndYear) > 0) {
- return 0;
- } else {
- result = 0;
- switch (_kind) {
- case E_repeatDaily:
- result = 1;
- break;
- case E_repeatWeekDaily:
- weekday = computeWeekday(day, month, year);
- result = (weekday != 1 && weekday != 7);
- break;
- case E_repeatWeekly:
- weekday = computeWeekday(day, month, year);
- result = (weekday == _weekday);
- break;
- case E_repeatBiWeekly:
- diff = computeDayDifference(day, month, year, _day, _month, _year);
- result = (diff % 14) == 0;
- break;
- case E_repeatMonthlyDate:
- result = (day == _day);
- break;
- case E_repeatMonthlyDay:
- weekday = computeWeekday(day, month, year);
- result = (weekday == _weekday && ((day-1)/7) == ((_day-1)/7));
- break;
- case E_repeatMonthlyDateEnd:
- result = (NumberOfDays(month, year)-day ==
- NumberOfDays(_month, _year)-_day);
- break;
- case E_repeatMonthlyDayEnd:
- weekday = computeWeekday(day, month, year);
- result = (weekday == _weekday &&
- (NumberOfDays(month, year)-day)/7 ==
- (NumberOfDays(_month, _year)-_day)/7);
- break;
- case E_repeatYearly:
- result = (_day == day && _month == month);
- break;
- case E_none:
- case E_single:
- default:
- break;
- }
- return result;
- }
- }
-
- void
- RepeatingEntry::setDate(int day, int month, int year)
- {
- Entry::setDate(day, month, year);
- _weekday = computeWeekday(day, month, year);
- }
-
- int
- RepeatingEntry::readEntry(FILE *fd, int version)
- {
- if (!Entry::readEntry(fd, version) ||
- !readInt(fd, &_repeatEndDay) ||
- !readInt(fd, &_repeatEndMonth) ||
- !readInt(fd, &_repeatEndYear)) {
- return 0;
- } else {
- return 1;
- }
- }
-
- void
- RepeatingEntry::writeEntry(FILE *fd, int annotate)
- {
- Entry::writeEntry(fd, annotate);
- writeInt(fd, _repeatEndDay, annotate ? "Repeat End Day" : NULL);
- writeInt(fd, _repeatEndMonth, annotate ? "Repeat End Month" : NULL);
- writeInt(fd, _repeatEndYear, annotate ? "Repeat End Year" : NULL);
- }
-
- int
- RepeatingEntry::daysInAdvance(int days, int d, int m, int y,
- int *matchDay, int *matchMonth, int *matchYear)
- {
- augmentDate(d, m, y, days, matchDay, matchMonth, matchYear);
- return repeatApplies(*matchDay, *matchMonth, *matchYear);
- }
-
- int
- RepeatingEntry::readDate(FILE *fd, int)
- {
- if (!readInt(fd, &_day) ||
- !readInt(fd, &_month) ||
- !readInt(fd, &_year)) {
- return 0;
- } else {
- // So that auxiliary computations occur
- setDate(_day, _month, _year);
- return 1;
- }
- }
-
- void
- RepeatingEntry::writeDate(FILE *fd, int annotate)
- {
- writeInt(fd, _day, annotate ? "Repeat Start Day" : NULL);
- writeInt(fd, _month, annotate ? "Repeat Start Month" : NULL);
- writeInt(fd, _year, annotate ? "Repeat Start Year" : NULL);
- }
-